/**
 * Nota.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package negocio.notas;

import java.io.IOException;
import java.util.Date;
import negocio.pessoas.Empreendimento;
import persistencia.notas.PNota;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class Nota {

    // <editor-fold defaultstate="collapsed" desc="FIELDS">
    static final private String K_BIND_CLASSNAME = "Nota";
    private String cod_objeto;
    private Integer numNota = 0;
    private String serie;
    private Date dtEmissao = null;
    private Date dtEntrada = null;
    private double valorNota = 0;
    private Integer situacao;
    private String fornecedor;
    private String empreendimento;
    protected Boolean update;
    protected Boolean isNew = true;
    protected String errorMessage = "";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="ACESSORES">
    // Atributo cod_objeto
    public String getCod_objeto() {
        return cod_objeto; }
    public void setCod_objeto(String cod_objeto) {
        this.cod_objeto = cod_objeto; }
    // Atributo numNota
    public Integer getNumNota() {
        return numNota; }
    public void setNumNota(Integer numNota) {
        this.numNota = numNota; }
    // Atributo serie
    public String getSerie() {
        return serie; }
    public void setSerie(String serie) {
        this.serie = serie; }
    // Atributo dtEmisao
    public Date getDtEmisao() {
        return dtEmissao; }
    public void setDtEmissao(Date dtEmissao) {
        this.dtEmissao = dtEmissao; }
    // Atributo dtEntrada
    public Date getDtEntrada() {
        return dtEntrada; }
    public void setDtEntrada(Date dtEntrada) {
        this.dtEntrada = dtEntrada; }
    // Atributo valorNota
    public double getValorNota() {
        return valorNota; }
    public void setValorNota(double valorNota) {
        this.valorNota = valorNota; }
    // Atributo situacao
    public Integer getSituacao() {
        return situacao; }
    public void setSituacao(Integer situacao) {
        this.situacao = situacao; }
    // Atributo fornecedor
    public String getFornecedor() {
        return fornecedor; }
    public void setFornecedor(String fornecedor) {
        this.fornecedor = fornecedor; }
    // Atributo empreendimento
    public String getEmpreendimento() {
        return empreendimento; }
    public void setEmpreendimento(String empreendimento) {
        this.empreendimento = empreendimento; }
    // Atributo update
    public Boolean getWasUpdated() {
        return update; }
    public void setWasUpdated(Boolean update) {
        this.update = update; }
    // Atributo isNew
    public Boolean getIsNew() {
        return isNew; }
    public void setIsNew(Boolean isNew) {
        this.isNew = isNew; }
    // Atributo classname
    public String getClassName() {
        return K_BIND_CLASSNAME; }
    // Atributo errorMessage
    public String getErrorMessage() {
        return errorMessage; }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    public Nota(){
        this.update  = false;
        this.isNew   = true;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="METHODS">
    /**
     * Verifica se um objeto e novo
     * @return retorna verdadeiro se o objeto for novo
     */
    public Boolean isNew(){
        return this.isNew;
    }

    /**
     * Realiza a delecao de um objeto na base de dados
     * @return TRUE se o objeto foi persistido e FALSE caso contrario
     */
    public Boolean delete() throws IOException{
        Boolean ret = true;

        // Verifica se um objeto e novo
        if(!this.isNew()){
            // Recupera o objeto empreendimento vinculado a nota
            Empreendimento emp = new Empreendimento();
            emp = emp.refresh(this.empreendimento);

            if(emp.getStatus() == StatusEmpreendimento.ABERTO){
                PNota pNota = new PNota();
                // Verifica se o objeto foi deletado com sucesso
                if(!pNota.delete(this)){
                    ret = false;
                    this.errorMessage = ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG;
                }
            }
            else{
                ret = false;
                errorMessage = ErrorMessage.MSG_NOTA_EXCLUSAO;
            }

        }
        else ret = false;

        return ret;
    }

    /**
     * Verifica a existencia de uma nota para um dado empreendimento
     * @return TRUE se o objeto foi persistido e FALSE caso contrario
     */
    public Boolean existsEmp(String idEmpreendimento) throws IOException{
        PNota pNota = new PNota();
        return pNota.existsEmp(idEmpreendimento);
    }

    /**
     * Verifica a existencia de uma nota para um dado fornecedor
     * @return TRUE se o objeto foi encontrado e FALSE caso contrario
     */
    public Boolean existsForn(String idFornecedor) throws IOException{
        PNota pNota = new PNota();
        return pNota.existsForn(idFornecedor);
    }

    /**
     * Verifica se ja existe uma nota com o numero e serie informado para o
     * fornecedor selecionado
     * @param numNota numero da nota a ser procurada
     * @param serie serie da nota a ser procurada
     * @param idForn identificador do fornecedor vinculado a nota
     * @param idNota identificador da nota
     * @return retorna verdadeiro se ja existe a nota cadastrada para o
     * fornecedor em questao e falso caso contrario
     */
    public Boolean exists(Integer numNota, String serie, String idForn,
                                                                String idNota){
        boolean exist = false;

        try{
            PNota pNota = new PNota();
            exist = pNota.exists(numNota, serie, idForn, idNota);
            this.errorMessage = pNota.isError() ?
                                    ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                    ErrorMessage.MSG_GERAL_LOG : "";
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            exist = false;
        }
        return exist;
    }

    /**
     * Recupera uma nota pelo seu codigo
     * @param idNota identificador da nota a ser procurada
     * @return a nota a ser recuperada
     */
    public Nota refresh(String idNota){
        Nota nota = null;

        try{

            // Verifica se foi informado algum codigo
            if(!idNota.isEmpty()){
                // Recupera a nota em questao
                nota = new Nota();
                PNota pNota = new PNota();
                nota = pNota.refresh(idNota);
                this.errorMessage = pNota.isError() ?
                                        ErrorMessage.MSG_GERAL_BANCO + "\n" +
                                        ErrorMessage.MSG_GERAL_LOG : "";
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            nota = null;
        }
        return nota;
    }

    // Realiza a validacao dos campos para insercao
    protected Boolean validateFields(){
        Boolean ret = true;

        // Verifica se o campo esta marcado como atualizado
        if(this.isNew()) this.cod_objeto = GenerateID.gerarID();

        ret = numNota > 0 ? true : false;

        if(ret){
            // Verifica se foi informado um fornecedor
            ret = this.fornecedor.isEmpty() ? false : true;
            
            if(ret){
                // Verifica se foi informado um empreendimento
                ret = this.empreendimento.isEmpty() ? false : true;                
                
                if(ret && !this.serie.isEmpty()){
                    ret = this.serie.length() > 3 ? false : true;                                    
                }
            }
        }

        if(ret){
            // Verifica se o valor do orcamento e maior que zero
            ret = this.valorNota > 0 ? true : false;

            if(ret){
                // Verifica se foi informada uma data de orcamento
                ret = this.dtEmissao != null ? true : false;


                // Caso tenha sido informada uma data de validade a mesma deve
                // ser superior a data do orcamento
                if(ret){
                    ret = this.dtEntrada != null ? true : false;

                    if(ret){
                        ret = this.dtEntrada.getTime() >=
                                      this.dtEmissao.getTime() ? true : false;

                        if(!ret) this.errorMessage = ErrorMessage.MSG_NOTA_DATA;
                    }
                }

                if(ret){
                    Date date = new Date();
                    ret = date.getTime() >= this.dtEntrada.getTime() ?
                                                                   true : false;
                    if(!ret) this.errorMessage = ErrorMessage.MSG_GERAL_DATA;
                }
            }
        }
        return ret;
    }
    //</editor-fold>
}